package tech.xs.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tech.xs.common.domain.enums.ImportTypeEnum;
import tech.xs.common.framework.domain.annotations.AuthApi;
import tech.xs.common.framework.domain.constant.DatePattern;
import tech.xs.common.framework.domain.constant.FileSuffixConstant;
import tech.xs.common.framework.domain.entity.BaseEntity;
import tech.xs.common.framework.domain.model.ApiResult;
import tech.xs.common.framework.domain.model.PageResult;
import tech.xs.common.framework.util.Assert;
import tech.xs.common.sys.domain.constant.PermissionConstant;
import tech.xs.sys.domain.bo.permission.EditPermissionBo;
import tech.xs.sys.domain.bo.permission.ExportPermissionQueryBo;
import tech.xs.sys.domain.bo.permission.ImportExportPermissionBo;
import tech.xs.sys.domain.bo.permission.PagePermissionBo;
import tech.xs.sys.domain.entity.SysPermission;
import tech.xs.sys.service.SysPermissionService;
import tech.xs.sys.service.SysRolePermissionService;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Validated
@RestController
@RequestMapping("/permission")
public class SysPermissionController {

    @Resource
    private SysPermissionService sysPermissionService;
    @Resource
    private SysRolePermissionService sysRolePermissionService;

    /**
     * 根据id更新或保存角色信息
     *
     * @param bo 请求参数
     * @return 响应数据
     * @author 沈家文
     * @since 2023/6/21 16:10
     */
    @PostMapping("/saveOrUpdate")
    @AuthApi(permissions = PermissionConstant.PERMISSION_MGR)
    public ApiResult<SysPermission> manualEdit(@Validated @RequestBody EditPermissionBo bo) {
        long existCount = sysPermissionService.count(Wrappers.<SysPermission>lambdaQuery()
                .eq(SysPermission::getCode, bo.getCode())
                .ne(bo.getId() != null, BaseEntity::getId, bo.getId()));
        if (existCount > 0) {
            return ApiResult.error("权限编码已经存在");
        }

        SysPermission saveData = new SysPermission();
        BeanUtil.copyProperties(bo, saveData);
        if (bo.getId() != null) {
            SysPermission dbData = sysPermissionService.getOne(Wrappers.<SysPermission>lambdaQuery().eq(BaseEntity::getId, bo.getId()));
            if (dbData == null) {
                return ApiResult.error("根据id在系统中未查询到数据");
            }
            boolean used = sysPermissionService.isUsed(dbData.getCode());
            if (!dbData.getCode().equals(bo.getCode()) && used) {
                return ApiResult.error("权限编码已经被使用,不允许修改");
            }
            if (used && bo.getPermissionStatus() != null && !dbData.getPermissionStatus().equals(bo.getPermissionStatus())) {
                sysRolePermissionService.deleteEnableRolePermissionCache();
            }
        }
        log.info("更新或保存权限:" + saveData);
        sysPermissionService.saveOrUpdate(saveData);
        return ApiResult.success(saveData);
    }

    /**
     * 根据权限编码删除权限
     *
     * @param permissionCode 权限编码
     * @return 响应数据
     * @author 沈家文
     * @since 2023/8/13 16:24
     */
    @DeleteMapping("/delete/code")
    @AuthApi(permissions = PermissionConstant.PERMISSION_MGR)
    public ApiResult<String> deleteByCode(@RequestParam String permissionCode) {
        if (StrUtil.isBlank(permissionCode)) {
            return ApiResult.error("[permissionCode]不能为空");
        }
        long count = sysPermissionService.count(Wrappers.<SysPermission>lambdaQuery().eq(SysPermission::getCode, permissionCode));
        if (count <= 0) {
            return ApiResult.error("权限不存在或已删除:" + permissionCode);
        }
        if (sysPermissionService.isUsed(permissionCode)) {
            return ApiResult.error("权限编码已经被使用,不允许删除");
        }
        log.info("删除权限:" + permissionCode);
        sysPermissionService.deletePermissionByCode(permissionCode);
        return ApiResult.success(permissionCode);
    }

    /**
     * 导出权限
     */
    @PostMapping("/export")
    @AuthApi(permissions = PermissionConstant.PERMISSION_MGR)
    public ResponseEntity<List<ImportExportPermissionBo>> exportPermission(@RequestBody ExportPermissionQueryBo bo) {
        String fileName = "权限导出_" + DateUtil.format(new Date(), DatePattern.UNSIGNED_NORM_DATETIME_PATTERN) + FileSuffixConstant.JSON;
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
        headers.add(HttpHeaders.CONTENT_TYPE, "application/json");

        List<ImportExportPermissionBo> res = new ArrayList<>();
        if (CollUtil.isNotEmpty(bo.getIds())) {
            List<SysPermission> dbData = sysPermissionService.list(bo.query());
            for (SysPermission dbItem : dbData) {
                ImportExportPermissionBo exportItem = new ImportExportPermissionBo();
                BeanUtil.copyProperties(dbItem, exportItem);
                exportItem.setImportType(ImportTypeEnum.addOrUpdate);
                res.add(exportItem);
            }
        }
        return ResponseEntity.ok().headers(headers).body(res);
    }

    /**
     * 导入权限
     */
    @PostMapping("/import")
    @AuthApi(permissions = PermissionConstant.PERMISSION_MGR)
    public ApiResult<Void> importPermission(@NotNull @RequestParam("file") MultipartFile file) throws IOException {
        String json = new String(file.getBytes());
        List<ImportExportPermissionBo> importDatas = JSONObject.parseArray(json, ImportExportPermissionBo.class);
        log.info("开始导入权限:" + importDatas);
        for (ImportExportPermissionBo importData : importDatas) {
            Assert.isNotBlank(importData.getCode(), "权限编码不能为空");
            Assert.isNotBlank(importData.getName(), "权限名称不能为空");
        }
        sysPermissionService.importPermission(importDatas);
        log.info("权限导入成功:" + importDatas);
        return ApiResult.success();
    }

    @GetMapping("/list/all")
    @AuthApi(permissions = {PermissionConstant.PERMISSION_MGR, PermissionConstant.ROLE_MGR})
    public ApiResult<List<SysPermission>> listAll() {
        return ApiResult.success(sysPermissionService.list(Wrappers.<SysPermission>lambdaQuery().orderByAsc(SysPermission::getCode)));
    }

    @GetMapping("/list/page")
    @AuthApi(permissions = PermissionConstant.PERMISSION_MGR)
    public PageResult<SysPermission> page(@ModelAttribute PagePermissionBo bo) {
        return PageResult.success(sysPermissionService.page(bo.page(), bo.query()));
    }


}
